package cn.com.wangluotongxin.linux.service.impl;

import cn.com.wangluotongxin.common.constants.CommonConstant;
import cn.com.wangluotongxin.common.exceptions.BadResponseException;
import cn.com.wangluotongxin.linux.dto.FolderInfoDto;
import cn.com.wangluotongxin.linux.form.DeleteDirForm;
import cn.com.wangluotongxin.linux.service.IFolderService;
import cn.com.wangluotongxin.linux.utils.SortUtil;
import cn.com.wangluotongxin.linux.vo.FolderInfoVo;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Service
public class FolderServiceImpl implements IFolderService {

    @Override
    public List<FolderInfoVo> list(FolderInfoDto dto) {
        File filePath = new File(dto.getPath());
        if(!filePath.exists()) {
            throw new BadResponseException("目录不存在");
        }
        List<FolderInfoVo> vos = new ArrayList<>();
        try {
            Stream<Path> pathStream = Files.list(filePath.toPath());
            for(Path streamPath : pathStream.collect(Collectors.toList())) {
                if(StrUtil.isNotBlank(dto.getFileName())) {
                    if (!FileUtil.getName(streamPath).contains(dto.getFileName())) continue;
                }

                FolderInfoVo vo = new FolderInfoVo();
                vo.setIsFolder(FileUtil.isDirectory(streamPath)? CommonConstant.ONE : CommonConstant.ZERO);
                vo.setFileName(FileUtil.getName(streamPath));
                BasicFileAttributes attributes = Files.readAttributes(streamPath, BasicFileAttributes.class);

                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
                if(attributes.creationTime() != null) {
                    // 文件创建时间
                    Instant createInstant = attributes.creationTime().toInstant();
                    LocalDateTime createDateTime = LocalDateTime.ofInstant(createInstant, ZoneId.systemDefault());
                    vo.setCreateTime(createDateTime.format(formatter));
                }
                if(attributes.lastModifiedTime() != null) {
                    // 文件最后修改时间
                    Instant modifyInstance = attributes.lastModifiedTime().toInstant();
                    LocalDateTime modifyDateTime = LocalDateTime.ofInstant(modifyInstance, ZoneId.systemDefault());
                    vo.setModifyTime(modifyDateTime.format(formatter));
                }
                vos.add(vo);
            }
        } catch (Exception ex) {
            log.error("读取文件目录异常:{}", ex.getMessage());
            throw new BadResponseException("文件目录读取失败");
        }
        if(dto.getOrderField().equals("isFolder")){
            vos = SortUtil.orderBy(JSONObject.parseArray(JSONObject.toJSONString(vos), Map.class), "isFolder", dto.getOrderBy(), Integer.class, FolderInfoVo.class);
        } else if(dto.getOrderField().equals("createTime")){
            vos = SortUtil.orderBy(JSONObject.parseArray(JSONObject.toJSONString(vos), Map.class), "createTime", dto.getOrderBy(), Date.class, FolderInfoVo.class);
        }if(dto.getOrderField().equals("modifyTime")){
            vos = SortUtil.orderBy(JSONObject.parseArray(JSONObject.toJSONString(vos), Map.class), "modifyTime", dto.getOrderBy(), Date.class, FolderInfoVo.class);
        }
        return vos;
    }

    @Override
    public void createDirectories(String path) {
        try {
            Path directory = Paths.get(path);
            if (Files.exists(directory)) {
                throw new BadResponseException("目录已存在");
            }
            // 目录不存在 创建新的目录
            Files.createDirectories(directory);
        } catch (IOException e) {
            log.error("创建目录异常:{}", e.getMessage());
            throw new BadResponseException(e.getMessage());
        }
    }

    @Override
    public void deleteDir(DeleteDirForm form) {
        try {
            String dirPath = form.getDirPath().concat("/").concat(form.getDirName());
            Path directory = Paths.get(dirPath);
            if (!Files.exists(directory)) {
                throw new BadResponseException("目录不存在");
            }
            if(!FileUtil.isDirectory(directory)) {
                throw new BadResponseException("请选择目录删除");
            }
            Stream<Path> pathStream = Files.list(directory);
            if(ArrayUtil.isAllNotEmpty(pathStream.collect(Collectors.toList()))) {
                throw new BadResponseException("有子目录或文件，不支持删除");
            }
            Files.delete(directory);
        } catch (Exception e) {
            log.error("删除目录异常:{}", e.getMessage());
            throw new BadResponseException(e.getMessage());
        }
    }

    @Override
    public void uploadDir(MultipartFile file, String filePath, String dirPath) {
        try {
            // 确保目录存在
            Path uploadDirectory = Paths.get(dirPath);
            if(!Files.exists(uploadDirectory)) {
                Files.createDirectories(uploadDirectory);
            }
            if(!Files.exists(uploadDirectory)) {
                throw new BadResponseException("目录创建失败:" + uploadDirectory.toString());
            }

            // 文件存储路径
            Path fileUploadPath = Paths.get(filePath);
            // 覆盖已存在的文件
            Files.copy(file.getInputStream(), fileUploadPath, StandardCopyOption.REPLACE_EXISTING);
        }catch (Exception ex) {
            log.error("目录上传失败:{}", ex.getMessage());
            throw new BadResponseException("目录上传失败");
        }
    }
}
